#include <iostream>
#include <string>
#include <thread>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#if defined(WIN32) || defined(WIN64) || defined(_WIN32) || defined(_WIN64)

#include <windows.h>


#define PIPE_NAME "\\\\.\\pipe\\MyNamedPipe"
#define BUFFER_SIZE 1024

void testClient()
{
    HANDLE hPipe;
    char buffer[BUFFER_SIZE];
    DWORD bytesRead, bytesWritten;

    // 连接到命名管道
    hPipe = CreateFile(
                PIPE_NAME,
                GENERIC_READ | GENERIC_WRITE,
                0,
                NULL,
                OPEN_EXISTING,
                FILE_FLAG_OVERLAPPED, // 设置为非阻塞模式
                NULL
                );

    if (hPipe == INVALID_HANDLE_VALUE) {
        printf("Failed to connect to named pipe. Error: %lu\n", GetLastError());
        return;
    }

    printf("Connected to server.\n");

    // 向服务器发送数据
    strcpy(buffer, "Hello, server!");
    if (!WriteFile(hPipe, buffer, strlen(buffer), &bytesWritten, NULL)) {
        printf("Failed to write to pipe. Error: %lu\n", GetLastError());
        CloseHandle(hPipe);
        return;
    }

    // 从服务器接收数据
    if (!ReadFile(hPipe, buffer, BUFFER_SIZE, &bytesRead, NULL)) {
        printf("Failed to read from pipe. Error: %lu\n", GetLastError());
        CloseHandle(hPipe);
        return;
    }

    buffer[bytesRead] = '\0';
    printf("Received from server: %s\n", buffer);

    CloseHandle(hPipe);
    return;
}

void testServer()
{
    HANDLE hPipe;
    char buffer[BUFFER_SIZE];
    DWORD bytesRead, bytesWritten;

    // 创建命名管道
    hPipe = CreateNamedPipe(
                PIPE_NAME,
                PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, // 双向访问，支持非阻塞
                PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,      // 字节模式
                PIPE_UNLIMITED_INSTANCES,                 // 最大实例数
                BUFFER_SIZE,                              // 输出缓冲区大小
                BUFFER_SIZE,                              // 输入缓冲区大小
                0,                                        // 默认超时时间
                NULL                                      // 默认安全属性
                );

    if (hPipe == INVALID_HANDLE_VALUE) {
        printf("Failed to create named pipe. Error: %lu\n", GetLastError());
        return;
    }
#if 0
    // 设置管道为非阻塞模式
    DWORD mode = PIPE_NOWAIT;
    if (!SetNamedPipeHandleState(hPipe, &mode, NULL, NULL)) {
        printf("Failed to set pipe to non-blocking mode. Error: %lu\n", GetLastError());
        CloseHandle(hPipe);
        return;
    }
#endif
    printf("Server: Named pipe created. Waiting for clients...\n");

    while (1) {
        // 等待客户端连接
        if (!ConnectNamedPipe(hPipe, NULL)) {
            DWORD dwError = GetLastError();
            if (dwError != ERROR_PIPE_CONNECTED && dwError != ERROR_IO_PENDING) {
                //printf("Failed to connect to client. Error: %lu\n", dwError);
                continue;
            }
        }

        printf("Client connected.\n");

        // 读取客户端发送的数据
        while (1) {
            if (!ReadFile(hPipe, buffer, BUFFER_SIZE, &bytesRead, NULL)) {
                DWORD dwError = GetLastError();
                if (dwError == ERROR_BROKEN_PIPE) {
                    printf("Client disconnected.\n");
                    break;
                } else {
                    printf("ReadFile failed with error: %lu\n", dwError);
                    break;
                }
            }

            if (bytesRead == 0) {
                printf("No data read. Client may have disconnected.\n");
                break;
            }

            buffer[bytesRead] = '\0';
            printf("Received from client: %s\n", buffer);

            // 回复客户端
            if (!WriteFile(hPipe, buffer, strlen(buffer), &bytesWritten, NULL)) {
                printf("Failed to write to pipe. Error: %lu\n", GetLastError());
                break;
            }
        }

        // 断开连接
        DisconnectNamedPipe(hPipe);
        //printf("Client disconnected.\n");
    }

    CloseHandle(hPipe);
    return;
}

// windows平台上使用共享内存模拟消息队列
void sender()
{
    // 连接共享内存
    HANDLE hMapFile = OpenFileMapping(
                FILE_MAP_ALL_ACCESS, // 读写权限
                FALSE, // 不继承句柄
                "MySharedMemory" // 共享内存名称
                );

    if (hMapFile == NULL) {
        printf("OpenFileMapping failed (%d)\n", GetLastError());
        return;
    }

    // 映射共享内存到进程地址空间
    LPVOID pBuf = MapViewOfFile(
                hMapFile, // 共享内存对象
                FILE_MAP_ALL_ACCESS, // 读写权限
                0, // 偏移高字序部分
                0, // 偏移低字序部分
                4096 // 映射大小
                );

    if (pBuf == NULL) {
        printf("MapViewOfFile failed (%d)\n", GetLastError());
        CloseHandle(hMapFile);
        return;
    }

    while (1) {
        // 读取数据
        char buffer[4096] = {0};
        CopyMemory(buffer, pBuf, sizeof(buffer));
        printf("Data read from shared memory: %s\n", buffer);

        // 写入数据（模拟数据交互）
        char message[] = "Hello from client";
        CopyMemory(pBuf, message, sizeof(message));
        Sleep(1000);
    }

    // 解除映射并关闭句柄
    UnmapViewOfFile(pBuf);
    CloseHandle(hMapFile);

    return;
}

void receiver()
{
    // 创建共享内存
    HANDLE hMapFile = CreateFileMapping(
                INVALID_HANDLE_VALUE, // 使用系统分页文件
                NULL, // 默认安全属性
                PAGE_READWRITE, // 读写权限
                0, // 最大大小高字序部分
                4096, // 最大大小低字序部分
                "MySharedMemory" // 共享内存名称
                );

    if (hMapFile == NULL) {
        printf("CreateFileMapping failed (%d)\n", GetLastError());
        return;
    }

    // 映射共享内存到进程地址空间
    LPVOID pBuf = MapViewOfFile(
                hMapFile, // 共享内存对象
                FILE_MAP_ALL_ACCESS, // 读写权限
                0, // 偏移高字序部分
                0, // 偏移低字序部分
                4096 // 映射大小
                );

    if (pBuf == NULL) {
        printf("MapViewOfFile failed (%d)\n", GetLastError());
        CloseHandle(hMapFile);
        return;
    }

    while (1) {
        // 写入数据
        char message[] = "Hello from server";
        CopyMemory(pBuf, message, sizeof(message));

        printf("Data written to shared memory\n");

        // 等待客户端读取数据
        Sleep(1000);

        // 读取数据（模拟数据交互）
        char buffer[4096] = {0};
        CopyMemory(buffer, pBuf, sizeof(buffer));
        printf("Data read from shared memory: %s\n", buffer);
    }

    // 解除映射并关闭句柄
    UnmapViewOfFile(pBuf);
    CloseHandle(hMapFile);
    return;
}

#endif

#if 0
int main(int argc, char **argv) {
    if (2 > argc) {
        printf("input agrv is error, must >= 2.\r\n");
        return 0;
    }

    if (0 == strcmp(argv[1], "A")) {
        //testServer();
        receiver();
    } else {
        //testClient();
        sender();
    }

    return 0;
}
#endif
